Moran_Scatterplot = Class.create(Configurable, {
    arr_data_x_ : new Array,
    arr_data_y_ : new Array,
    arr_ids_ : new Array,
    max_x_ : 0,
    min_x_ : 0,
    max_y_ : 0,
    min_y_ : 0,
    initialize: function(options) 
    {
        this.setOptions(options);
        this.readData();
        if(this.arr_data_y_.length != this.arr_data_x_.length || this.arr_ids_.length != this.arr_data_x_.length)
        {
            alert('Something went wrong!');
            return false;
        }
        this.createScatterplot();
    },
    readData : function()
    {
        $$('.w_value').each(function(element){
            var value = parseFloat(element.innerHTML); 
            if(value > this.max_x_)
                this.max_x_ = Math.ceil(value);
            if(value < this.min_x_)
                this.min_x_ = Math.floor(value);
            this.arr_data_x_.push(value);
        }.bind(this));
        if(Math.abs(this.min_x_) > Math.abs(this.max_x_))
            this.max_x_ = Math.abs(this.min_x_);
        else
            this.min_x_ = -Math.abs(this.max_x_);
        $$('.w_n_value').each(function(element){
            var value = parseFloat(element.innerHTML); 
            if(value > this.max_y_)
                this.max_y_ = Math.ceil(value);
            if(value < this.min_y_)
                this.min_y_ = Math.floor(value);
            this.arr_data_y_.push(value);
        }.bind(this));
        if(Math.abs(this.min_y_) > Math.abs(this.max_y_))
            this.max_y_ = Math.abs(this.min_y_);
        else
            this.min_y_ = -Math.abs(this.max_y_);
        $$('.plot_value').each(function(element){
            this.arr_ids_.push(element.id);
        }.bind(this));
    },
    createScatterplot : function()
    {
        var cpp_x, cpp_y, height, plot_height, plot_width, pos_x, pos_y, moran, ml_y1, ml_y2;
        moran = parseFloat($('morans_i').innerHTML);
        height = $(this.options.scatterplot_holder_id).getHeight();
        plot_height = height-2*this.options.scatterplot_margin;
        plot_width = this.options.scatterplot_width-this.options.scatterplot_margin*2;
        raphael = Raphael(this.options.scatterplot_holder_id, this.options.scatterplot_width, height);
        //cases per pixel
        cpp_x = (this.max_x_-this.min_x_) / plot_width;
        cpp_y = (this.max_y_-this.min_y_) / plot_height;
        var box = raphael.rect(this.options.scatterplot_margin, this.options.scatterplot_margin, plot_width, plot_height);
        var x_line = raphael.path("M"+this.options.scatterplot_margin+" "+ (this.options.scatterplot_margin+Math.round(this.max_y_/cpp_y))+"L"+(plot_width+this.options.scatterplot_margin)+" "+ (this.options.scatterplot_margin+Math.round(this.max_y_/cpp_y)));
        var y_line = raphael.path("M"+(this.options.scatterplot_margin+Math.round(Math.abs(this.min_x_)/cpp_x))+" "+ this.options.scatterplot_margin+"L"+(this.options.scatterplot_margin+Math.round(Math.abs(this.min_x_)/cpp_x))+" "+ (this.options.scatterplot_margin+plot_height));
        ml_y1 = (this.options.scatterplot_margin+Math.round(this.max_y_/cpp_y)+Math.abs(Math.round(moran*this.min_x_/cpp_y)));
        if(ml_y1 > (this.options.scatterplot_margin+plot_height))
            ml_y1 = this.options.scatterplot_margin+plot_height;
        ml_y2 = (this.options.scatterplot_margin+Math.round(this.max_y_/cpp_y)-Math.abs(Math.round(moran*this.max_x_/cpp_y)));
        if(ml_y2 < this.options.scatterplot_margin)
            ml_y2 = this.options.scatterplot_margin;
        var moran_line = raphael.path("M"+this.options.scatterplot_margin+" "+ ml_y1+"L"+(plot_width+this.options.scatterplot_margin)+" "+ ml_y2);
        for(cnt=0; cnt < this.arr_data_x_.length; ++cnt)
        {
            if(this.min_x_ < 0)
                pos_x = Math.round((this.arr_data_x_[cnt]+Math.abs(this.min_x_))/cpp_x);
            else
                pos_x = Math.round(this.arr_data_x_[cnt]/cpp_x);
            if(this.arr_data_y_[cnt] < 0)
                pos_y = Math.round((this.max_y_ + Math.abs(this.arr_data_y_[cnt]))/cpp_y);
            else
                pos_y = Math.round((this.max_y_ - this.arr_data_y_[cnt])/cpp_y);
            var c = raphael.circle(pos_x+this.options.scatterplot_margin, pos_y+this.options.scatterplot_margin, 5);
            c.attr({fill: "yellow", opacity: 0.6, "href" : "#"+this.arr_ids_[cnt]});
        }
        this.addEventListener();
    },
    addEventListener : function()
    {
        if("onhashchange" in window || Prototype.Browser.Opera)
        {       
            window.onhashchange = this.checkHash.bind(this);
            this.hideTable();
        }
    },
    hideTable : function()
    {
        var arr_rows = $(this.arr_ids_[0]).up().rows;
        for(var cnt=0; cnt < arr_rows.length; ++cnt)
            arr_rows[cnt].hide();
    },
    checkHash : function()
    {
        this.hideTable();
        if(window.location.hash.indexOf('plot_value') != -1)
        {
            $(window.location.hash.gsub('#', '')).show();
        }
    }
});

Moran_Scatterplot.DEFAULT_OPTIONS = {
    scatterplot_holder_id: 'scatterplot',
    scatterplot_width: 400,
    scatterplot_margin: 40
};

new Moran_Scatterplot();
